;实验10 子程序1：在指定的位置用指定的颜色，显示一个以0结尾的字符串

;子程序名字：show_str
;参数：(dh)=行号(取值范围：0-24)，(dl)=列号(取值范围：0-79)，(cl)=颜色
		;ds:si指向字符串的首地址
		
;主程序目标：在8行3列显示一个绿色的字符串：Welcome to masm!
assume cs:code
data segment
	db 'Welcome to masm!',0 
data ends

code segment
	start:	mov dh,8	;行 
			mov dl,3	;列 
			mov cl,2	;2为绿色
			mov ax,data
			mov ds,ax
			mov si,0	;首地址为0
			call show_str
			
			mov ax,4c00h
			int 21h
	;子程序设计 开始：(B8000-BFFFF为dos显存地址空间)
	show_str:	
				;子程序要完成的主要任务是把ds:[si]的位置的字符串复制到指定的显存地址空间中
				;第二个任务是颜色的修改
				;看看能否直接找出行列和显存空间的对应公式？

				;行*列：40*80
				;0行：b800:0000 - b800:009f,1行：b800:00a0 - b800:013f,2行：0140-....0140+9f
				;总结得出行列对应的显存位移公式：行=dh*A0 ,列=dl*2(0:0,1:2,2:4,3:6...)
				push ax
				push es
				push dx
				push bx
				push cx
				push si
				push di 
				mov ax,0b800h
				mov es,ax					;显存基地址
				mov ax,0
				mov di,0
				
				mov al,dh
				mov bl,0a0h
				mul bl 						;把0a0h和al相乘，存到ax中(所在行位置)
				mov bx,ax					;行存在bx里
				
				mov al,dl
				mov ah,0 
				mov ah,2
				mul ah
				add bx,ax 					;bx保存显存偏移地址~ax中存的是列号
				
				mov dh,cl					;颜色 存到dh中，8位正好，cl不方便（后面判断用到jcxz）
	l:	
				mov cl,[si]
				mov ch,0 
				mov ax,ds:[si]
				mov es:[di+bx],ax
				mov es:[di+1+bx],dh 
				jcxz ok
				inc si
				add di,2
				jmp l
				ok:	
				pop di
				pop si
				pop cx
				pop bx
				pop dx
				pop es
				pop ax 
				ret
	
code ends
end start